package cn.good.yan.sf.t7;

/**
 * 7 表达式
 * 后缀表达式
 * 中缀表达式
 *
 * @author shengren.yan
 * @create 2024-07-27
 */
public class Expressions {

    // 后缀表达式 : 计算机计算    2 1 + 3 *  =  (2+1)*3      4 13 5 / +  =  4 + ( 13 / 5)
    public static int postfix(String[] arr) {
        ArrayStack<Integer> stack = new ArrayStack<>(arr.length);
        for (int i = 0; i < arr.length; i++) {
            String c = arr[i];
            Integer b = 0;
            Integer a = 0;
            switch (c) {
                case "+":
                    b = stack.pol();
                    a = stack.pol();
                    stack.push(a + b);
                    break;
                case "-":
                    b = stack.pol();
                    a = stack.pol();
                    stack.push(a - b);
                    break;
                case "*":
                    b = stack.pol();
                    a = stack.pol();
                    stack.push(a * b);
                    break;
                case "/":
                    b = stack.pol();
                    a = stack.pol();
                    stack.push(a / b);
                    break;
                default:
                    // 是数字，进行入栈
                    stack.push(Integer.valueOf(c));
            }

        }
        return stack.pol();
    }

    // 中缀表达式  : 计算机计算
    // 公式：优先级 比 栈优先级高的，入栈，否则 把>=它的，都出栈
    // 带（ 直接入栈 ，带 ） 把栈里不是左括号的，都出栈，（也出栈
    // a+b          ab+
    // a+b-c        ab+c-
    // a*b+c        ab*c+
    // a+b*c        abc*+
    // a+b*c-d      abc*+d-
    // (a+b)*c      ab+c*
    // (a+b*c-d)*e  abc*+d-e*
    // a*(b+c)      abc+*
    public static String centre(String arr) throws Exception {
        ArrayStack<String> stack = new ArrayStack<>(arr.length());
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < arr.length(); i++) {
            String t = String.valueOf(arr.charAt(i));
            if (t.equals("+") || t.equals("-") || t.equals("*") || t.equals("/")) {
                if (stack.isEmpty()) {
                    stack.push(t);
                } else {
                    if (priority(t) > priority(stack.peek())) {
                        stack.push(t);
                    } else {
                        while (!stack.isEmpty() && priority(t) <= priority(stack.peek())) {
                            String pol = stack.pol();
                            builder.append(pol);
                        }
                        stack.push(t);
                    }
                }
            } else if (t.equals("(")) {
                stack.push("(");
            } else if (t.equals(")")) {
                while (!stack.isEmpty() && !stack.peek().equals("(")) {
                    String pol = stack.pol();
                    builder.append(pol);
                }
                String pol = stack.pol(); // 把（ 也进行出栈
            } else {
                builder.append(t);
            }

        }
        while (!stack.isEmpty()) {
            builder.append(stack.pol());
        }
        return builder.toString();
    }

    public static int priority(String str) throws Exception {
        int n = 0;
        switch (str) {
            case "+":
                n = 1;
                break;
            case "-":
                n = 1;
                break;
            case "*":
                n = 2;
                break;
            case "/":
                n = 2;
                break;
            case "(":
                n = 0;
                break;
            case ")":
                n = 0;
                break;
            default:
                throw new Exception("符合不正确");
        }
        return n;
    }

    public static void main(String[] args) throws Exception {

        // 后缀表达式
        System.out.println("------------【后缀表达式】--------------");
        String[] a1 = {"2", "1", "+", "3", "*"};          // 9     （2+1）* 3
        System.out.println(postfix(a1));
        String[] a2 = {"4", "13", "5", "/", "+"};         // 6      4 + (13/5)
        System.out.println(postfix(a2));
        System.out.println("------------【后缀表达式】--------------");

        // 中缀表达式
        System.out.println("------------【中缀表达式】--------------");
        System.out.println(centre("a+b"));           // ab+
        System.out.println(centre("a+b-c"));         // ab+c-
        System.out.println(centre("a*b+c"));         // ab*c+
        System.out.println(centre("a+b*c"));         // abc*+
        System.out.println(centre("a+b*c-d"));       // abc*+d-
        System.out.println(centre("(a+b)*c"));       // ab+c*
        System.out.println(centre("(a+b*c-d)*e"));   // abc*+d-e*
        System.out.println(centre("a*(b+c)"));       // abc+*
        System.out.println("------------【中缀表达式】--------------");

    }


}
